package hacker_rank.a_star;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;

public class PacManBFS {

	static void nextMove(int r, int c, int pacman_r, int pacman_c, int food_r,
			int food_c, String[] grid) {

		boolean[][] vis = new boolean[r][c];
		for (boolean[] v : vis)
			Arrays.fill(v, false);

		Queue<Node> st = new LinkedList<Node>();
		Map<Node, Node> parentMap = new HashMap<Node, Node>();
		Set<Node> exploredNodes = new LinkedHashSet<Node>();

		Node pacman = new Node(pacman_r, pacman_c);
		st.offer(pacman);

		exploredNodes.add(pacman);
		parentMap.put(pacman, null);

		while (!st.isEmpty()) {
			Node t = st.poll();

			exploredNodes.add(t);
			if (grid[t.x].charAt(t.y) == '.') {
				break;
			}
			for (Node n : getAdjacentNodes(grid, r, c, t)) {
				if (vis[n.x][n.y] == false) {
					parentMap.put(n, t);
					st.offer(n);
				}
			}
			vis[t.x][t.y] = true;
		}

		System.out.println(exploredNodes.size());
		for (Node t : exploredNodes)
			System.out.printf("%d %d\n", t.x, t.y);

		Stack<Node> pathStack = new Stack<Node>();
		Node t = new Node(food_r, food_c);
		while (t != null) {
			pathStack.push(t);
			t = parentMap.get(t);
		}

		System.out.println(pathStack.size() - 1);

		while (!pathStack.isEmpty()) {
			Node p = pathStack.pop();
			System.out.printf("%d %d\n", p.x, p.y);
		}

	}

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

		String line = br.readLine();

		int pacman_r = Integer.parseInt(line.split(" ")[0]);
		int pacman_c = Integer.parseInt(line.split(" ")[1]);

		line = br.readLine();

		int food_r = Integer.parseInt(line.split(" ")[0]);
		int food_c = Integer.parseInt(line.split(" ")[1]);

		line = br.readLine();

		int r = Integer.parseInt(line.split(" ")[0]);
		int c = Integer.parseInt(line.split(" ")[1]);

		String[] grid = new String[r];

		for (int i = 0; i < r; i++) {
			grid[i] = br.readLine();
		}

		nextMove(r, c, pacman_r, pacman_c, food_r, food_c, grid);
	}

	static Collection<Node> getAdjacentNodes(String[] grid, int r, int c, Node n) {
		List<Node> li = new ArrayList<Node>();

		// UP
		if (n.x - 1 >= 0 && grid[n.x - 1].charAt(n.y) != '%')
			li.add(new Node(n.x - 1, n.y));

		// LEFT
		if (n.y - 1 >= 0 && grid[n.x].charAt(n.y - 1) != '%') {
			li.add(new Node(n.x, n.y - 1));
		}

		// RIGHT
		if (n.y + 1 < c && grid[n.x].charAt(n.y + 1) != '%')
			li.add(new Node(n.x, n.y + 1));

		if (n.x + 1 < r && grid[n.x + 1].charAt(n.y) != '%')
			li.add(new Node(n.x + 1, n.y));

		return li;
	}

	public static class Node {
		public int x;
		public int y;

		public Node(int x, int y) {
			this.x = x;
			this.y = y;
		}

		@Override
		public boolean equals(Object obj) {
			if (obj instanceof Node == false) {
				return false;
			}
			Node t = (Node) obj;
			if (this.x == t.x && this.y == t.y)
				return true;
			else
				return false;
		}

		@Override
		public int hashCode() {
			return (this.x * 13 * 13) + (this.y * 13);
		}

	}
}
